package controlSoftware.userThread;

import java.io.IOException;
import java.util.Queue;
import java.util.logging.FileHandler;
import java.util.logging.Logger;

import controlSoftware.view.viewController;

public class UserThread implements Runnable {
	private Logger LOGGER;
	final int SLEEPTIME = (int)SysModel.sampleTime;
	String threadName;
	
	// Queue with IMU data
	Queue<SensorData> rawDataQueue;
	
	// Queue with converted acceleration and gyroscope data
	//Queue<SensorData> rawData = new ConcurrentLinkedQueue<SensorData>();
	
	SensorData currentData;
	KalmanFilter userFilter = new KalmanFilter();
	viewController viewControl = new viewController();
	
	Velocity prevVelocity; 
	Coordinate prevCoordinate;

	public UserThread(String threadName, Queue<SensorData> cache) {
		this.threadName = threadName;
		this.rawDataQueue = cache;
		this.prevVelocity =  SysModel.initVelocity;
		this.prevCoordinate = SysModel.initCoordinate;
		
	}

	public String getName() {
		return threadName;
	}

	public SensorData getNextFromQueue() {
		// returns head of queue, or null if empty
		return rawDataQueue.poll();
	}

	@Override
	public void run() {
		//create log file
		try{
		FileHandler handler = new FileHandler("log/outputData.log", false);
		LOGGER = Logger.getLogger(UserThread.class
				.getName());
		LOGGER.addHandler(handler); 
		}
		catch(IOException e){
			System.out.println("Output Data Log Generation Error!\n");
		}
		
		while (true) {
			// get raw data from cache
			if (!rawDataQueue.isEmpty()) {
				currentData = this.getNextFromQueue();
			} else {
				currentData = null; // reset currentData
			}

			if (currentData != null) {
				//convert raw data to values
				//currentData.processRaw();
				
				// TODO: apply kalman filter
				
				//calc and store velocity
				prevVelocity = currentData.getVelocity(prevVelocity);
				
				//calculate displacement
				currentData.getDisplacement();
				
				//calculate new coordinate
				currentData.getCoordinate(prevCoordinate);
							
				// pass on the data to view handler to handle
				viewControl.updateView(currentData, prevCoordinate);
				
				//store new coordinate
				prevCoordinate = currentData.currLoc;

				// log data
				LOGGER.info( this.getName() + " active: \n"
						+ "Coordinate X: " + currentData.currLoc.getX()
						+ " Coordinate Y: " + currentData.currLoc.getY());
			}

			try {
				Thread.sleep(SLEEPTIME);
			} catch (InterruptedException e) {
				LOGGER.severe("UserThread interrupted.");
			}
		}
	}
}